github.com-freelawproject-x-ray_-_2025-12-24_01-37-04
Item Preview
Share or Embed This Item
- Publication date
- 2025-12-24
- Topics
- GitHub, code, software, git
- Item Size
- 8.4M
A tool to detect whether a PDF has a bad redaction

x-ray is a Python library for finding bad redactions in PDF documents.
Why?
At Free Law Project, we collect millions of PDFs. An ongoing problemis that people fail to properly redact things. Instead of doing it the rightway, they just draw a black rectangle or a black highlight on top of blacktext and call it a day. Well, when that happens you just select the text underthe rectangle, and you can read it again. Not great.
After witnessing this problem for years, we decided it would be good to figureout how common it is, so, with some help, we built this simple tool. You givethe tool the path to a PDF. It tells you if it has worthless redactions in it.
What next?
Right now, x-ray works pretty well and we are using it to analyze documentsin our collections. It could be better though. Bad redactions take many forms.See the issues tab for other examples we don't yet support. We'd love yourhelp solving some of tougher cases.
Installation
With uv, do:
textuv add x-ray
With pip, that'd be:textpip install x-ray
Usage
uvx lets you run this without even installing it. For example, here's an amicus brief we filed that doesn't have any bad redactions:
uvx --from x-ray xray https://storage.courtlistener.com/recap/gov.uscourts.ca3.125346/gov.uscourts.ca3.125346.45.0.pdf{}
Once you do install x-ray, you can easily use it on the command line. Once installed, just:
bash% xray path/to/your/file.pdf{ "1": [ { "bbox": [ 58.550079345703125, 72.19873046875, 75.65007781982422, 739.3987426757812 ], "text": "The Ring travels by way of Cirith Ungol" } ]}
Or if you have the file on a server somewhere, give it a URL. If it starts with https://, it will be interpreted as a PDF to download. Here's congressional testimony our director made (it doesn't have any bad redactions):
bash% xray https://free.law/pdf/congressional-testimony-michael-lissner-free-law-project-hearing-on-ethics-and-transparency-2021-10-26.pdf{}
A fun trick you can do is to make a file with one URL per line, call it urls.txt. Then you can run this to check each URL:
bashxargs -n 1 xray < urls.txt
However you run xray on the command line, you'll get JSON as output. When you have that, you can use it with tools like jq. The format is as follows:
- It's a dict.
- The keys are page numbers.
- Each page number maps to a list of dicts.
- Each of those dicts maps to two keys.
- The first key is
bbox. This is a four-tuple that indicates the x,y positions of the upper left corner and then lower right corners of the bad redaction. - The second key is
text. This is the text under the bad rectangle.
Simple enough.
You can also use it as a Python module, if you prefer the long-form:
% python -m xray some-file.pdf
But that's not as easy to remember.
If you want a bit more, you can, of course, use xray in Python:
pythonfrom pprint import pprintimport xraybad_redactions = xray.inspect("some/path/to/your/file.pdf") # Pathlib works toopprint(bad_redactions){1: [{'bbox': (58.550079345703125, 72.19873046875, 75.65007781982422, 739.3987426757812), 'text': 'Aragorn is the one true king.'}]}
The output is the same as above, except it's a Python object, not a JSON object.
If you already have the file contents as a bytes object, that'll work too:
pythonsome_bytes = requests.get("https://lotr-secrets.com/some-doc.pdf").contentbad_redactions = xray.inspect(some_bytes)
Note that because the inspect method uses the same signature no matter what,the type of the object you give it is essential:
Input | xray's Assumption-- | --str or Pathlib Path | local filestr that starts with https:// | URL to downloadbytes | PDF in memory
This means that if you provide the filename on disk as a bytes object insteadof a str, it's not going to work. This will fail:
pythonxray.inspect(b"some-file-path.pdf")
That's pretty much it. There are no configuration files or other variables tolearn. You give it a file name. If there is a bad redaction in it, you'll soonfind out.
How it works
Under the covers, xray uses the high-performant PyMuPDF project to parse PDFs. It has been a wonderful project to work with.
You can read the source to see how it works, but the general idea is to:
Find rectangles in a PDF.
Find letters in the same location
Render the rectangle as an image
Inspect the rectangle to see if it's all one color. If it is, then that's abad redaction. If not, then we assume you can see a mix of text anddrawings, indicating a redaction that's OK.
The PDF format is a big and complicated one, so it's difficult to do all this perfectly. We do our best, but there's always more to do to make it better. Donations and sponsored work help.
Contributions
Please see the issues list on Github for things we need, or start a conversation if you have questions. Before you do your first contribution, we'll need a signed contributor license agreement. See the template in the repo.
Deployment
Releases happen automatically via Github Actions. To trigger an automated build:
Update CHANGES.md
Update the version in pyproject.toml
Tag the commit with something like "v0.0.0".
If you wish to create a new version manually, the process is:
Update version info in
pyproject.tomlConfigure your Pypi credentials with Poetry
Build and publish the version:
shpoetry publish --build
License
This repository is available under the permissive BSD license, making it easy and safe to incorporate in your own libraries.
Pull and feature requests welcome. Online editing in GitHub is possible (and easy!).
To restore the repository download the bundle
wget https://archive.org/download/github.com-freelawproject-x-ray_-_2025-12-24_01-37-04/freelawproject-x-ray_-_2025-12-24_01-37-04.bundle and run: git clone freelawproject-x-ray_-_2025-12-24_01-37-04.bundle Source: https://github.com/freelawproject/x-ray
Uploader: freelawproject
Upload date: 2025-12-24
- Addeddate
- 2025-12-24 04:45:13
- Identifier
- github.com-freelawproject-x-ray_-_2025-12-24_01-37-04
- Originalurl
- https://github.com/freelawproject/x-ray
- Pushed_date
- 2025-12-24 01:37:04
- Scanner
- Internet Archive Python library 5.4.0
- Uploaded_with
- iagitup - v1.6.2
- Year
- 2025
Open Library